/**
 * 
 */
package hichecker.ui.components.custom_table.table_header_renderer;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.TableCellRenderer;

/**
 *
 */
public class MultiLineHeaderRenderer extends JPanel implements TableCellRenderer {
	
	protected int verticalAlignment;
	protected int horizontalAlignment;
	protected float alignmentX;

	protected Color foreground;
	protected Color background;
	
	protected Font font;

	protected TableCellRenderer oldRenderer;
	
	/**
	 * Creates the renderer
	 * @param horizontalAlignment
	 * @param verticalAlignment
	 */
	public MultiLineHeaderRenderer(TableCellRenderer oldRenderer, int horizontalAlignment,
			int verticalAlignment) {
		this.horizontalAlignment = horizontalAlignment;
		this.verticalAlignment = verticalAlignment;
		this.oldRenderer = oldRenderer;
		
		// Set the horziontal alignment
		switch (horizontalAlignment) {
			case SwingConstants.LEFT:
				alignmentX = (float) 0.0;
				break;
			case SwingConstants.CENTER:
				alignmentX = (float) 0.5;
				break;
			case SwingConstants.RIGHT:
				alignmentX = (float) 1.0;
				break;
			default:
				throw new IllegalArgumentException("Illegal horizontal alignment value");
		}
		
		// Set the border and the layout of the component
		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		setOpaque(true);

		background = null;
	}
	
	@Override
	public void setForeground(Color foreground) {
		this.foreground = foreground;
		super.setForeground(foreground);
	}

	@Override
	public void setBackground(Color background) {
		this.background = background;
		super.setBackground(background);
	}

	@Override
	public void setFont(Font font) {
		this.font = font;
	}

	@Override
	public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
			boolean hasFocus, int row, int column) {
		
		removeAll();
		invalidate();

		// Do nothing if no value
		if (value == null) {
			return this;
		}
		
		Component oldComp = oldRenderer.getTableCellRendererComponent(table, value, isSelected,
				hasFocus, row, column);

		setFont(oldComp.getFont());
		setForeground(oldComp.getBackground());
		setBackground(oldComp.getForeground());
		setBounds(oldComp.getBounds());
		
		// If the vertical alignment isn't top create a glue component
		if (verticalAlignment != SwingConstants.TOP) {
			add(Box.createVerticalGlue());
		}

		Object[] values;
		int length;
		
		// Get the value and turn it into an array, if it's not already one
		if (value instanceof Object[]) {
			values = (Object[]) value;
		} else {
			values = new Object[1];
			values[0] = value;
		}
		length = values.length;

		for (int i = 0; i < length; i++) {
			Object rowValue = values[i];
			
			// The value is already a JComponent so use it as it is
			if (rowValue instanceof JComponent) {
				add((JComponent) rowValue);
			// The value is something else so create a JLabel and add the value
			} else {
				JLabel label = new JLabel();
				setValue(label, rowValue, i);
				add(label);
			}
		}

		// If the vertical alignment isn't bottom create a glue component
		if (verticalAlignment != SwingConstants.BOTTOM) {
			add(Box.createVerticalGlue());
		}
		
		// Return component
		return this;
	}

	/**
	 * Configures a label so it's a line of the table header
	 * 
	 * @param label
	 * @param value
	 *            if it's an icon it's put as the label icon, else the labels text is set to {@code
	 *            value.getString()}
	 * @param lineNumber
	 */
	protected void setValue(JLabel label, Object value, int lineNumber) {
		
		label.setText(value == null ? "" : value.toString());
		
		// Set icon or text
		if (value != null && value instanceof Icon) {
			label.setIcon((Icon) value);
		} else {
			label.setText(value == null ? "" : value.toString());
		}
		
		// Set the same alignment and foreground values as the header
		label.setHorizontalAlignment(horizontalAlignment);
		label.setAlignmentX(alignmentX);
		label.setOpaque(false);
		label.setForeground(foreground);
		label.setFont(font);
	}
}
